#!/usr/bin/python
# use N95 as mouse, xdotool/xdpyinfo must be installed 
# select "mouse" filter in TkSID or start with 
# command line standalone

import sys, os, time
from Sensor import Sensor, SensorReceiver

# xdpyinfo get dimension
def getdimension():
    lines = os.popen("xdpyinfo").readlines()
    line = [l for l in lines if "dimensions:" in l][0]
    dim = line.split()[1]
    dimx, dimy = map(int, dim.split("x"))
    return dimx, dimy

# xdotool abstraction
def getmouselocation():
    s = os.popen("xdotool getmouselocation").read()
    return tuple(map(lambda x: int(x.split(':')[1]), s.split()[:2]))

def movemouse(x, y):
    os.popen("xdotool mousemove %d %d" % (x,y)).read()

LEFT = 1
MIDDLE = 2
RIGHT = 3
def mouseclick(button=LEFT):
    os.popen("xdotool click %d" % button)

def mousedown(button=LEFT):
    os.popen("xdotool mousedown %d" % button)

def mouseup(button=LEFT):
    os.popen("xdotool mouseup %d" % button)

class MouseControl(object):
    def __init__(self, x_max=1399, y_max=1049, standalone=False):
        self.x_max, self.y_max = x_max, y_max
        self.x, self.y = getmouselocation()
        self.standalone = standalone
        if self.standalone:
            # standalone, not depending on TkSID.py
            # that is how one would write a final application ready to use
            self.sensor = Sensor()
            sys.path.append("filters")    # use the filter defined in subdir
            from mousefilter import mouse # normally that would be in this file as well 
            self.sensor.register_filter(mouse)
            self.sensor.register_sink(self.react) # slow callback; but hopefully ok
            self.sensor.start_receiving()
        else:
            # run through TkSID.py/depending on Sensor and distribution
            # that is how on would test and develop the application
            self.sensor_receiver = SensorReceiver()
            self.sensor_receiver.register(self.react)
    def react(self, dic):
        if "up" in dic:
            # print "up", dic["up"]
            mouseup(int(dic["up"]))
        if "down" in dic:
            # print "down", dic["down"]
            mousedown(int(dic["down"]))
        if "click" in dic:
            # print "click", dic["click"]
            mouseclick(int(dic["click"]))
        move_x = 0
        if "xmove" in dic:
            move_x = dic["xmove"]
        move_y = 0
        if "ymove" in dic:
            move_y = dic["ymove"]
        if move_x or move_y:
            # self.x, self.y = getmouselocation()
            self.x, self.y = self.x+move_x, self.y+move_y
            if self.x < 0:
                self.x = 0
            if self.y < 0:
                self.y = 0
            if self.x > self.x_max:
                self.x = self.x_max
            if self.y > self.y_max:
                self.y = self.y_max
            # print self.x, self.y, move_x, move_y
            movemouse(self.x, self.y)
        # print dic
    def close(self):
        print "closing"
        if self.standalone:
            self.sensor.stop_receiving()
        else:
            self.sensor_receiver.close()



if __name__ == '__main__':
    print "Use sensor input (N95) to control the mouse"
    print "xdotool/xdpyinfo must be installed and you must run X"
    print "Start TkSID.py and select (only) the mouse filter or"
    print "start with commandline argument 'standalone'."
    print "Hold the phone such that the keys look away from you"
    print "# left, 0 middle, * right mouse button"
    print "turn left to go left and move towards you to go up"
    print "press Ctrl-C to stop"
    try:
        x,y = getdimension()
    except:
        x,y = 1400, 1050
    if "standalone" in sys.argv:
        mouse_control = MouseControl(x_max=x-1, y_max=y-1, standalone=True)
    else:
        mouse_control = MouseControl(x_max=x-1, y_max=y-1)
    try:
        time.sleep(2**30)
    except:
        print "interrupted"
    mouse_control.close()
